home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / xlib / tlogo.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  52KB  |  1,802 lines

  1. /*
  2.  * (c) Copyright 1993-94, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include <GL/glu.h>
  39. #include <GL/glx.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <X11/keysym.h>
  43. #include <string.h>
  44. #include <math.h>
  45. #ifdef unix
  46. #include <sys/times.h>
  47. #include <sys/param.h>
  48. #endif
  49.  
  50. #define    BLACK    0
  51. #define    GRAY    (1 << (indexBits - 1))
  52. #define    WHITE    ((1 << indexBits) - 1)
  53.  
  54. #define PI 3.141592654
  55.  
  56. static int RGBA_SB_attributes[] = {
  57.     GLX_RGBA,
  58.     GLX_ACCUM_RED_SIZE, 1,
  59.     GLX_RED_SIZE, 1,
  60.     GLX_GREEN_SIZE, 1,
  61.     GLX_BLUE_SIZE, 1,
  62.     GLX_DEPTH_SIZE, 1,
  63.     GLX_STENCIL_SIZE, 1,
  64.     None,
  65. };
  66.  
  67. static int RGBA_DB_attributes[] = {
  68.     GLX_RGBA,
  69.     GLX_ACCUM_RED_SIZE, 1,
  70.     GLX_RED_SIZE, 1,
  71.     GLX_GREEN_SIZE, 1,
  72.     GLX_BLUE_SIZE, 1,
  73.     GLX_DOUBLEBUFFER,
  74.     GLX_DEPTH_SIZE, 1,
  75.     GLX_STENCIL_SIZE, 1,
  76.     None,
  77. };
  78.  
  79. static int CI_SB_attributes[] = {
  80.     GLX_DEPTH_SIZE, 1,
  81.     GLX_STENCIL_SIZE, 1,
  82.     None,
  83. };
  84.  
  85. static int CI_DB_attributes[] = {
  86.     GLX_DOUBLEBUFFER,
  87.     GLX_DEPTH_SIZE, 1,
  88.     GLX_STENCIL_SIZE, 1,
  89.     None,
  90. };
  91.  
  92. static Display *dpy;
  93. static Colormap cmap;
  94. static Window window;
  95. static GLint indexBits;
  96. static char *fontName
  97.     = "-adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1";
  98. static long fontBase;
  99. static long fontWidth, fontHeight;
  100.  
  101. static float black[3] = {0.0, 0.0, 0.0};
  102. static float white[3] = {1.0, 1.0, 1.0};
  103. static float gray[3] =  {0.5, 0.5, 0.5};
  104. static float blue[3] =  {0.0, 0.0, 1.0};
  105.  
  106. static long W = 300, H = 300;
  107.  
  108. static float xRotation = 30.0, yRotation = 30.0;
  109. static float zTranslation = -15.0;
  110. static double plane[4] = {1.0, 0.0, -1.0, 0.0};
  111. static GLint colorIndexes[3] = {0, 200, 255};
  112.  
  113. static long singleCylinder;
  114. static long doubleCylinder;
  115. static long elbow, logo;
  116.  
  117. static long imageComponents = 3;
  118. static long dodither = 1;
  119. static long lighting = 1;
  120. static long twoside = 1;
  121. static long depth = 1;
  122. static long fog = 0;
  123. static long rgb = 1;
  124. static long clipPlane = 1;
  125. static long doubleBuffer = 1;
  126. static long clearMask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
  127. static long polymode = GL_FRONT_AND_BACK;
  128. static long capping;
  129. static long culling;
  130. static long cullface;
  131. static long texturing;
  132. static long jittering;
  133. static long motionblur;
  134. static long feedbackmode;
  135. #define MAX_FEED    1048576        /* 4 meg worth of floats */
  136. static GLfloat feedbackBuf[MAX_FEED];
  137.  
  138. static long decimation = 1;    /* Decimate image into 1x1 subimages */
  139.  
  140. #define Bl 0x00
  141. #define Wh 0xff
  142. #define    checkImageWidth 8
  143. #define    checkImageHeight 8
  144. static unsigned char checkImage[3*checkImageWidth*checkImageHeight] = {
  145.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  146.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  147.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  148.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  149.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  150.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  151.     Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,
  152.     Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,Wh,Wh,Wh,Bl,Bl,Bl,
  153. };
  154.  
  155. #define Rd 0xa40000ff
  156. #define Wt 0xffffffff
  157. #define    brickImageWidth 16
  158. #define    brickImageHeight 16
  159. static unsigned long brickImage[brickImageWidth*brickImageHeight] = {
  160.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  161.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  162.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  163.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd,
  164.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  165.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  166.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  167.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  168.     Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd,
  169.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  170.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  171.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  172.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  173.     Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd,
  174.     Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt, Wt,
  175.     Rd, Rd, Rd, Rd, Wt, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Rd, Wt, Rd
  176. };
  177.  
  178. static unsigned char* image = checkImage;
  179. static long imageHeight = checkImageHeight;
  180. static long imageWidth = checkImageWidth;
  181.  
  182. static float decal[] = {
  183.     GL_DECAL,
  184. };
  185. static float modulate[] = {
  186.     GL_MODULATE,
  187. };
  188. static float repeat[] = {
  189.     GL_REPEAT,
  190. };
  191. static float nearest[] = {
  192.     GL_NEAREST,
  193. };
  194.  
  195. static unsigned char stipple[4*32] = {
  196.     0x00, 0x00, 0x00, 0x00,
  197.     0x00, 0x00, 0x00, 0x00,
  198.     0x00, 0x00, 0x00, 0x00,
  199.     0x00, 0x00, 0x00, 0x00,
  200.     0x00, 0x00, 0x00, 0x00,
  201.     0x00, 0x00, 0x00, 0x00,
  202.     0x00, 0x00, 0x00, 0x00,
  203.     0x00, 0x00, 0x00, 0x00,
  204.  
  205.     0x00, 0x0F, 0xF0, 0x00,
  206.     0x00, 0x0F, 0xF0, 0x00,
  207.     0x00, 0x0F, 0xF0, 0x00,
  208.     0x00, 0x0F, 0xF0, 0x00,
  209.     0x00, 0x0F, 0xF0, 0x00,
  210.     0x00, 0x0F, 0xF0, 0x00,
  211.     0x00, 0x0F, 0xF0, 0x00,
  212.     0x00, 0x0F, 0xF0, 0x00,
  213.  
  214.     0x00, 0x0F, 0xF0, 0x00,
  215.     0x00, 0x0F, 0xF0, 0x00,
  216.     0x00, 0x0F, 0xF0, 0x00,
  217.     0x00, 0x0F, 0xF0, 0x00,
  218.     0x00, 0x0F, 0xF0, 0x00,
  219.     0x00, 0x0F, 0xF0, 0x00,
  220.     0x00, 0x0F, 0xF0, 0x00,
  221.     0x00, 0x0F, 0xF0, 0x00,
  222.  
  223.     0x00, 0x00, 0x00, 0x00,
  224.     0x00, 0x00, 0x00, 0x00,
  225.     0x00, 0x00, 0x00, 0x00,
  226.     0x00, 0x00, 0x00, 0x00,
  227.     0x00, 0x00, 0x00, 0x00,
  228.     0x00, 0x00, 0x00, 0x00,
  229.     0x00, 0x00, 0x00, 0x00,
  230.     0x00, 0x00, 0x00, 0x00,
  231. };
  232.  
  233. static float tscp[18][2] = {
  234.     {0.0, 0.0},     {1.0, 0.0},
  235.     {0.0, .125}, {1.0, .125},
  236.     {0.0, .250}, {1.0, .25},
  237.     {0.0, .375}, {1.0, .375},
  238.     {0.0, .50},     {1.0, .50},
  239.     {0.0, .625}, {1.0, .625},
  240.     {0.0, .75},     {1.0, .75},
  241.     {0.0, .875}, {1.0, .875},
  242.     {0.0, 1.0},     {1.0, 1.0},
  243. };
  244.  
  245. static float scp[18][3] = {
  246.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 5.000000},
  247.     {0.707107, 0.707107, 0.000000},    {0.707107, 0.707107, 5.000000},
  248.     {0.000000, 1.000000, 0.000000},    {0.000000, 1.000000, 5.000000},
  249.     {-0.707107, 0.707107, 0.000000},    {-0.707107, 0.707107, 5.000000},
  250.     {-1.000000, 0.000000, 0.000000},    {-1.000000, 0.000000, 5.000000},
  251.     {-0.707107, -0.707107, 0.000000},    {-0.707107, -0.707107, 5.000000},
  252.     {0.000000, -1.000000, 0.000000},    {0.000000, -1.000000, 5.000000},
  253.     {0.707107, -0.707107, 0.000000},    {0.707107, -0.707107, 5.000000},
  254.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 5.000000},
  255. };
  256.  
  257. static float dcp[18][3] = {
  258.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 7.000000},
  259.     {0.707107, 0.707107, 0.000000},    {0.707107, 0.707107, 7.000000},
  260.     {0.000000, 1.000000, 0.000000},    {0.000000, 1.000000, 7.000000},
  261.     {-0.707107, 0.707107, 0.000000},    {-0.707107, 0.707107, 7.000000},
  262.     {-1.000000, 0.000000, 0.000000},    {-1.000000, 0.000000, 7.000000},
  263.     {-0.707107, -0.707107, 0.000000},    {-0.707107, -0.707107, 7.000000},
  264.     {0.000000, -1.000000, 0.000000},    {0.000000, -1.000000, 7.000000},
  265.     {0.707107, -0.707107, 0.000000},    {0.707107, -0.707107, 7.000000},
  266.     {1.000000, 0.000000, 0.000000},    {1.000000, 0.000000, 7.000000},
  267. };
  268.  
  269. static float ep[7][9][3] = {
  270.     {
  271.     {1.000000, 0.000000, 0.000000},
  272.     {0.707107, 0.707107, 0.000000},
  273.     {0.000000, 1.000000, 0.000000},
  274.     {-0.707107, 0.707107, 0.000000},
  275.     {-1.000000, 0.000000, 0.000000},
  276.     {-0.707107, -0.707107, 0.000000},
  277.     {0.000000, -1.000000, 0.000000},
  278.     {0.707107, -0.707107, 0.000000},
  279.     {1.000000, 0.000000, 0.000000},
  280.     },
  281.     {
  282.     {1.000000, 0.034074, 0.258819},
  283.     {0.707107, 0.717087, 0.075806},
  284.     {0.000000, 1.000000, 0.000000},
  285.     {-0.707107, 0.717087, 0.075806},
  286.     {-1.000000, 0.034074, 0.258819},
  287.     {-0.707107, -0.648939, 0.441832},
  288.     {0.000000, -0.931852, 0.517638},
  289.     {0.707107, -0.648939, 0.441832},
  290.     {1.000000, 0.034074, 0.258819},
  291.     },
  292.     {
  293.     {1.000000, 0.133975, 0.500000},
  294.     {0.707107, 0.746347, 0.146447},
  295.     {0.000000, 1.000000, 0.000000},
  296.     {-0.707107, 0.746347, 0.146447},
  297.     {-1.000000, 0.133975, 0.500000},
  298.     {-0.707107, -0.478398, 0.853553},
  299.     {0.000000, -0.732051, 1.000000},
  300.     {0.707107, -0.478398, 0.853553},
  301.     {1.000000, 0.133975, 0.500000},
  302.     },
  303.     {
  304.     {1.000000, 0.292893, 0.707107},
  305.     {0.707107, 0.792893, 0.207107},
  306.     {0.000000, 1.000000, 0.000000},
  307.     {-0.707107, 0.792893, 0.207107},
  308.     {-1.000000, 0.292893, 0.707107},
  309.     {-0.707107, -0.207107, 1.207107},
  310.     {0.000000, -0.414214, 1.414214},
  311.     {0.707107, -0.207107, 1.207107},
  312.     {1.000000, 0.292893, 0.707107},
  313.     },
  314.     {
  315.     {1.000000, 0.500000, 0.866025},
  316.     {0.707107, 0.853553, 0.253653},
  317.     {0.000000, 1.000000, 0.000000},
  318.     {-0.707107, 0.853553, 0.253653},
  319.     {-1.000000, 0.500000, 0.866025},
  320.     {-0.707107, 0.146447, 1.478398},
  321.     {0.000000, 0.000000, 1.732051},
  322.     {0.707107, 0.146447, 1.478398},
  323.     {1.000000, 0.500000, 0.866025},
  324.     },
  325.     {
  326.     {1.000000, 0.741181, 0.965926},
  327.     {0.707107, 0.924194, 0.282913},
  328.     {0.000000, 1.000000, 0.000000},
  329.     {-0.707107, 0.924194, 0.282913},
  330.     {-1.000000, 0.741181, 0.965926},
  331.     {-0.707107, 0.558168, 1.648939},
  332.     {0.000000, 0.482362, 1.931852},
  333.     {0.707107, 0.558168, 1.648939},
  334.     {1.000000, 0.741181, 0.965926},
  335.     },
  336.     {
  337.     {1.000000, 1.000000, 1.000000},
  338.     {0.707107, 1.000000, 0.292893},
  339.     {0.000000, 1.000000, 0.000000},
  340.     {-0.707107, 1.000000, 0.292893},
  341.     {-1.000000, 1.000000, 1.000000},
  342.     {-0.707107, 1.000000, 1.707107},
  343.     {0.000000, 1.000000, 2.000000},
  344.     {0.707107, 1.000000, 1.707107},
  345.     {1.000000, 1.000000, 1.000000},
  346.     },
  347. };
  348.  
  349. static float en[7][9][3] = {
  350.     {
  351.     {1.000000, 0.000000, 0.000000},
  352.     {0.707107, 0.707107, 0.000000},
  353.     {0.000000, 1.000000, 0.000000},
  354.     {-0.707107, 0.707107, 0.000000},
  355.     {-1.000000, 0.000000, 0.000000},
  356.     {-0.707107, -0.707107, 0.000000},
  357.     {0.000000, -1.000000, 0.000000},
  358.     {0.707107, -0.707107, 0.000000},
  359.     {1.000000, 0.000000, 0.000000},
  360.     },
  361.     {
  362.     {1.000000, 0.000000, 0.000000},
  363.     {0.707107, 0.683013, -0.183013},
  364.     {0.000000, 0.965926, -0.258819},
  365.     {-0.707107, 0.683013, -0.183013},
  366.     {-1.000000, 0.000000, 0.000000},
  367.     {-0.707107, -0.683013, 0.183013},
  368.     {0.000000, -0.965926, 0.258819},
  369.     {0.707107, -0.683013, 0.183013},
  370.     {1.000000, 0.000000, 0.000000},
  371.     },
  372.     {
  373.     {1.000000, 0.000000, 0.000000},
  374.     {0.707107, 0.612372, -0.353553},
  375.     {0.000000, 0.866025, -0.500000},
  376.     {-0.707107, 0.612372, -0.353553},
  377.     {-1.000000, 0.000000, 0.000000},
  378.     {-0.707107, -0.612372, 0.353553},
  379.     {0.000000, -0.866025, 0.500000},
  380.     {0.707107, -0.612372, 0.353553},
  381.     {1.000000, 0.000000, 0.000000},
  382.     },
  383.     {
  384.     {1.000000, 0.000000, 0.000000},
  385.     {0.707107, 0.612372, -0.500000},
  386.     {0.000000, 0.707107, -0.707107},
  387.     {-0.707107, 0.500000, -0.500000},
  388.     {-1.000000, 0.000000, 0.000000},
  389.     {-0.707107, -0.500000, 0.500000},
  390.     {0.000000, -0.707107, 0.707107},
  391.     {0.707107, -0.500000, 0.500000},
  392.     {1.000000, 0.000000, 0.000000},
  393.     },
  394.     {
  395.     {1.000000, 0.000000, 0.000000},
  396.     {0.707107, 0.353553, -0.612372},
  397.     {0.000000, 0.500000, -0.866025},
  398.     {-0.707107, 0.353553, -0.612372},
  399.     {-1.000000, 0.000000, 0.000000},
  400.     {-0.707107, -0.353553, 0.612372},
  401.     {0.000000, -0.500000, 0.866025},
  402.     {0.707107, -0.353553, 0.612372},
  403.     {1.000000, 0.000000, 0.000000},
  404.     },
  405.     {
  406.     {1.000000, 0.000000, 0.000000},
  407.     {0.707107, 0.183013, -0.683013},
  408.     {0.000000, 0.258819, -0.965926},
  409.     {-0.707107, 0.183013, -0.683013},
  410.     {-1.000000, 0.000000, 0.000000},
  411.     {-0.707107, -0.183013, 0.683013},
  412.     {0.000000, -0.258819, 0.965926},
  413.     {0.707107, -0.183013, 0.683013},
  414.     {1.000000, 0.000000, 0.000000},
  415.     },
  416.     {
  417.     {1.000000, 0.000000, 0.000000},
  418.     {0.707107, 0.000000, -0.707107},
  419.     {0.000000, 0.000000, -1.000000},
  420.     {-0.707107, 0.000000, -0.707107},
  421.     {-1.000000, 0.000000, 0.000000},
  422.     {-0.707107, 0.000000, 0.707107},
  423.     {0.000000, 0.000000, 1.000000},
  424.     {0.707107, 0.000000, 0.707107},
  425.     {1.000000, 0.000000, 0.000000},
  426.     },
  427. };
  428.  
  429. static float tep[7][9][2] = {
  430.     {
  431.     {0,     0.0},
  432.     {0.125, 0.0},
  433.     {0.25,  0.0},
  434.     {0.375, 0.0},
  435.     {0.5,   0.0},
  436.     {0.625, 0.0},
  437.     {0.75,  0.0},
  438.     {0.875, 0.0},
  439.     {1.0,   0.0},
  440.     },
  441.     {
  442.     {0,     0.16667},
  443.     {0.125, 0.16667},
  444.     {0.25,  0.16667},
  445.     {0.375, 0.16667},
  446.     {0.5,   0.16667},
  447.     {0.625, 0.16667},
  448.     {0.75,  0.16667},
  449.     {0.875, 0.16667},
  450.     {1.0,   0.16667},
  451.     },
  452.     {
  453.     {0,     0.33333},
  454.     {0.125, 0.33333},
  455.     {0.25,  0.33333},
  456.     {0.375, 0.33333},
  457.     {0.5,   0.33333},
  458.     {0.625, 0.33333},
  459.     {0.75,  0.33333},
  460.     {0.875, 0.33333},
  461.     {1.0,   0.33333},
  462.     },
  463.     {
  464.     {0,     0.5},
  465.     {0.125, 0.5},
  466.     {0.25,  0.5},
  467.     {0.375, 0.5},
  468.     {0.5,   0.5},
  469.     {0.625, 0.5},
  470.     {0.75,  0.5},
  471.     {0.875, 0.5},
  472.     {1.0,   0.5},
  473.     },
  474.     {
  475.     {0,     0.6667},
  476.     {0.125, 0.6667},
  477.     {0.25,  0.6667},
  478.     {0.375, 0.6667},
  479.     {0.5,   0.6667},
  480.     {0.625, 0.6667},
  481.     {0.75,  0.6667},
  482.     {0.875, 0.6667},
  483.     {1.0,   0.6667},
  484.     },
  485.     {
  486.     {0,     0.83333},
  487.     {0.125, 0.83333},
  488.     {0.25,  0.83333},
  489.     {0.375, 0.83333},
  490.     {0.5,   0.83333},
  491.     {0.625, 0.83333},
  492.     {0.75,  0.83333},
  493.     {0.875, 0.83333},
  494.     {1.0,   0.83333},
  495.     },
  496.     {
  497.     {0,     1.0},
  498.     {0.125, 1.0},
  499.     {0.25,  1.0},
  500.     {0.375, 1.0},
  501.     {0.5,   1.0},
  502.     {0.625, 1.0},
  503.     {0.75,  1.0},
  504.     {0.875, 1.0},
  505.     {1.0,   1.0},
  506.     }
  507. };
  508.  
  509. static void Build_single_cylinder(void)
  510. {
  511.     float st[2];
  512.  
  513.     glNewList(singleCylinder, GL_COMPILE);
  514.     glBegin(GL_TRIANGLE_STRIP);
  515.        glNormal3fv(scp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(scp[0]);
  516.        glNormal3fv(scp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(scp[1]);
  517.        glNormal3fv(scp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(scp[2]);
  518.        glNormal3fv(scp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(scp[3]);
  519.        glNormal3fv(scp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(scp[4]);
  520.        glNormal3fv(scp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(scp[5]);
  521.        glNormal3fv(scp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(scp[6]);
  522.        glNormal3fv(scp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(scp[7]);
  523.        glNormal3fv(scp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(scp[8]);
  524.        glNormal3fv(scp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(scp[9]);
  525.        glNormal3fv(scp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(scp[10]);
  526.        glNormal3fv(scp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(scp[11]);
  527.        glNormal3fv(scp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(scp[12]);
  528.        glNormal3fv(scp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(scp[13]);
  529.        glNormal3fv(scp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(scp[14]);
  530.        glNormal3fv(scp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(scp[15]);
  531.        glNormal3fv(scp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(scp[16]);
  532.        glNormal3fv(scp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(scp[17]);
  533.     glEnd();
  534.     glEndList();
  535. }
  536.  
  537. static void Build_double_cylinder(void)
  538. {
  539.     float st[2];
  540.  
  541.     glNewList(doubleCylinder, GL_COMPILE);
  542.     glBegin(GL_TRIANGLE_STRIP);
  543.     glNormal3fv(dcp[0]); glTexCoord2fv(tscp[0]); glVertex3fv(dcp[0]);
  544.     glNormal3fv(dcp[0]); glTexCoord2fv(tscp[1]); glVertex3fv(dcp[1]);
  545.     glNormal3fv(dcp[2]); glTexCoord2fv(tscp[2]); glVertex3fv(dcp[2]);
  546.     glNormal3fv(dcp[2]); glTexCoord2fv(tscp[3]); glVertex3fv(dcp[3]);
  547.     glNormal3fv(dcp[4]); glTexCoord2fv(tscp[4]); glVertex3fv(dcp[4]);
  548.     glNormal3fv(dcp[4]); glTexCoord2fv(tscp[5]); glVertex3fv(dcp[5]);
  549.     glNormal3fv(dcp[6]); glTexCoord2fv(tscp[6]); glVertex3fv(dcp[6]);
  550.     glNormal3fv(dcp[6]); glTexCoord2fv(tscp[7]); glVertex3fv(dcp[7]);
  551.     glNormal3fv(dcp[8]); glTexCoord2fv(tscp[8]); glVertex3fv(dcp[8]);
  552.     glNormal3fv(dcp[8]); glTexCoord2fv(tscp[9]); glVertex3fv(dcp[9]);
  553.     glNormal3fv(dcp[10]); glTexCoord2fv(tscp[10]); glVertex3fv(dcp[10]);
  554.     glNormal3fv(dcp[10]); glTexCoord2fv(tscp[11]); glVertex3fv(dcp[11]);
  555.     glNormal3fv(dcp[12]); glTexCoord2fv(tscp[12]); glVertex3fv(dcp[12]);
  556.     glNormal3fv(dcp[12]); glTexCoord2fv(tscp[13]); glVertex3fv(dcp[13]);
  557.     glNormal3fv(dcp[14]); glTexCoord2fv(tscp[14]); glVertex3fv(dcp[14]);
  558.     glNormal3fv(dcp[14]); glTexCoord2fv(tscp[15]); glVertex3fv(dcp[15]);
  559.     glNormal3fv(dcp[16]); glTexCoord2fv(tscp[16]); glVertex3fv(dcp[16]);
  560.     glNormal3fv(dcp[16]); glTexCoord2fv(tscp[17]); glVertex3fv(dcp[17]);
  561.     glEnd();
  562.     glEndList();
  563. }
  564.  
  565. static void Build_elbow(void)
  566. {
  567.     float st[2];
  568.  
  569.     glNewList(elbow, GL_COMPILE);
  570.     glBegin(GL_TRIANGLE_STRIP);
  571.     glNormal3fv(en[0][0]); glTexCoord2fv(tep[0][0]); glVertex3fv(ep[0][0]);
  572.     glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
  573.     glNormal3fv(en[0][1]); glTexCoord2fv(tep[0][1]); glVertex3fv(ep[0][1]);
  574.     glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
  575.     glNormal3fv(en[0][2]); glTexCoord2fv(tep[0][2]); glVertex3fv(ep[0][2]);
  576.     glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
  577.     glNormal3fv(en[0][3]); glTexCoord2fv(tep[0][3]); glVertex3fv(ep[0][3]);
  578.     glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
  579.     glNormal3fv(en[0][4]); glTexCoord2fv(tep[0][4]); glVertex3fv(ep[0][4]);
  580.     glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
  581.     glNormal3fv(en[0][5]); glTexCoord2fv(tep[0][5]); glVertex3fv(ep[0][5]);
  582.     glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
  583.     glNormal3fv(en[0][6]); glTexCoord2fv(tep[0][6]); glVertex3fv(ep[0][6]);
  584.     glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
  585.     glNormal3fv(en[0][7]); glTexCoord2fv(tep[0][7]); glVertex3fv(ep[0][7]);
  586.     glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
  587.     glNormal3fv(en[0][8]); glTexCoord2fv(tep[0][8]); glVertex3fv(ep[0][8]);
  588.     glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
  589.     glEnd();
  590.     glBegin(GL_TRIANGLE_STRIP);
  591.     glNormal3fv(en[1][0]); glTexCoord2fv(tep[1][0]); glVertex3fv(ep[1][0]);
  592.     glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
  593.     glNormal3fv(en[1][1]); glTexCoord2fv(tep[1][1]); glVertex3fv(ep[1][1]);
  594.     glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
  595.     glNormal3fv(en[1][2]); glTexCoord2fv(tep[1][2]); glVertex3fv(ep[1][2]);
  596.     glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
  597.     glNormal3fv(en[1][3]); glTexCoord2fv(tep[1][3]); glVertex3fv(ep[1][3]);
  598.     glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
  599.     glNormal3fv(en[1][4]); glTexCoord2fv(tep[1][4]); glVertex3fv(ep[1][4]);
  600.     glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
  601.     glNormal3fv(en[1][5]); glTexCoord2fv(tep[1][5]); glVertex3fv(ep[1][5]);
  602.     glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
  603.     glNormal3fv(en[1][6]); glTexCoord2fv(tep[1][6]); glVertex3fv(ep[1][6]);
  604.     glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
  605.     glNormal3fv(en[1][7]); glTexCoord2fv(tep[1][7]); glVertex3fv(ep[1][7]);
  606.     glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
  607.     glNormal3fv(en[1][8]); glTexCoord2fv(tep[1][8]); glVertex3fv(ep[1][8]);
  608.     glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
  609.     glEnd();
  610.     glBegin(GL_TRIANGLE_STRIP);
  611.     glNormal3fv(en[2][0]); glTexCoord2fv(tep[2][0]); glVertex3fv(ep[2][0]);
  612.     glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
  613.     glNormal3fv(en[2][1]); glTexCoord2fv(tep[2][1]); glVertex3fv(ep[2][1]);
  614.     glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
  615.     glNormal3fv(en[2][2]); glTexCoord2fv(tep[2][2]); glVertex3fv(ep[2][2]);
  616.     glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
  617.     glNormal3fv(en[2][3]); glTexCoord2fv(tep[2][3]); glVertex3fv(ep[2][3]);
  618.     glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
  619.     glNormal3fv(en[2][4]); glTexCoord2fv(tep[2][4]); glVertex3fv(ep[2][4]);
  620.     glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
  621.     glNormal3fv(en[2][5]); glTexCoord2fv(tep[2][5]); glVertex3fv(ep[2][5]);
  622.     glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
  623.     glNormal3fv(en[2][6]); glTexCoord2fv(tep[2][6]); glVertex3fv(ep[2][6]);
  624.     glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
  625.     glNormal3fv(en[2][7]); glTexCoord2fv(tep[2][7]); glVertex3fv(ep[2][7]);
  626.     glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
  627.     glNormal3fv(en[2][8]); glTexCoord2fv(tep[2][8]); glVertex3fv(ep[2][8]);
  628.     glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
  629.     glEnd();
  630.     glBegin(GL_TRIANGLE_STRIP);
  631.     glNormal3fv(en[3][0]); glTexCoord2fv(tep[3][0]); glVertex3fv(ep[3][0]);
  632.     glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
  633.     glNormal3fv(en[3][1]); glTexCoord2fv(tep[3][1]); glVertex3fv(ep[3][1]);
  634.     glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
  635.     glNormal3fv(en[3][2]); glTexCoord2fv(tep[3][2]); glVertex3fv(ep[3][2]);
  636.     glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
  637.     glNormal3fv(en[3][3]); glTexCoord2fv(tep[3][3]); glVertex3fv(ep[3][3]);
  638.     glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
  639.     glNormal3fv(en[3][4]); glTexCoord2fv(tep[3][4]); glVertex3fv(ep[3][4]);
  640.     glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
  641.     glNormal3fv(en[3][5]); glTexCoord2fv(tep[3][5]); glVertex3fv(ep[3][5]);
  642.     glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
  643.     glNormal3fv(en[3][6]); glTexCoord2fv(tep[3][6]); glVertex3fv(ep[3][6]);
  644.     glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
  645.     glNormal3fv(en[3][7]); glTexCoord2fv(tep[3][7]); glVertex3fv(ep[3][7]);
  646.     glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
  647.     glNormal3fv(en[3][8]); glTexCoord2fv(tep[3][8]); glVertex3fv(ep[3][8]);
  648.     glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
  649.     glEnd();
  650.     glBegin(GL_TRIANGLE_STRIP);
  651.     glNormal3fv(en[4][0]); glTexCoord2fv(tep[4][0]); glVertex3fv(ep[4][0]);
  652.     glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
  653.     glNormal3fv(en[4][1]); glTexCoord2fv(tep[4][1]); glVertex3fv(ep[4][1]);
  654.     glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
  655.     glNormal3fv(en[4][2]); glTexCoord2fv(tep[4][2]); glVertex3fv(ep[4][2]);
  656.     glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
  657.     glNormal3fv(en[4][3]); glTexCoord2fv(tep[4][3]); glVertex3fv(ep[4][3]);
  658.     glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
  659.     glNormal3fv(en[4][4]); glTexCoord2fv(tep[4][4]); glVertex3fv(ep[4][4]);
  660.     glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
  661.     glNormal3fv(en[4][5]); glTexCoord2fv(tep[4][5]); glVertex3fv(ep[4][5]);
  662.     glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
  663.     glNormal3fv(en[4][6]); glTexCoord2fv(tep[4][6]); glVertex3fv(ep[4][6]);
  664.     glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
  665.     glNormal3fv(en[4][7]); glTexCoord2fv(tep[4][7]); glVertex3fv(ep[4][7]);
  666.     glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
  667.     glNormal3fv(en[4][8]); glTexCoord2fv(tep[4][8]); glVertex3fv(ep[4][8]);
  668.     glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
  669.     glEnd();
  670.     glBegin(GL_TRIANGLE_STRIP);
  671.     glNormal3fv(en[5][0]); glTexCoord2fv(tep[5][0]); glVertex3fv(ep[5][0]);
  672.     glNormal3fv(en[6][0]); glTexCoord2fv(tep[6][0]); glVertex3fv(ep[6][0]);
  673.     glNormal3fv(en[5][1]); glTexCoord2fv(tep[5][1]); glVertex3fv(ep[5][1]);
  674.     glNormal3fv(en[6][1]); glTexCoord2fv(tep[6][1]); glVertex3fv(ep[6][1]);
  675.     glNormal3fv(en[5][2]); glTexCoord2fv(tep[5][2]); glVertex3fv(ep[5][2]);
  676.     glNormal3fv(en[6][2]); glTexCoord2fv(tep[6][2]); glVertex3fv(ep[6][2]);
  677.     glNormal3fv(en[5][3]); glTexCoord2fv(tep[5][3]); glVertex3fv(ep[5][3]);
  678.     glNormal3fv(en[6][3]); glTexCoord2fv(tep[6][3]); glVertex3fv(ep[6][3]);
  679.     glNormal3fv(en[5][4]); glTexCoord2fv(tep[5][4]); glVertex3fv(ep[5][4]);
  680.     glNormal3fv(en[6][4]); glTexCoord2fv(tep[6][4]); glVertex3fv(ep[6][4]);
  681.     glNormal3fv(en[5][5]); glTexCoord2fv(tep[5][5]); glVertex3fv(ep[5][5]);
  682.     glNormal3fv(en[6][5]); glTexCoord2fv(tep[6][5]); glVertex3fv(ep[6][5]);
  683.     glNormal3fv(en[5][6]); glTexCoord2fv(tep[5][6]); glVertex3fv(ep[5][6]);
  684.     glNormal3fv(en[6][6]); glTexCoord2fv(tep[6][6]); glVertex3fv(ep[6][6]);
  685.     glNormal3fv(en[5][7]); glTexCoord2fv(tep[5][7]); glVertex3fv(ep[5][7]);
  686.     glNormal3fv(en[6][7]); glTexCoord2fv(tep[6][7]); glVertex3fv(ep[6][7]);
  687.     glNormal3fv(en[5][8]); glTexCoord2fv(tep[5][8]); glVertex3fv(ep[5][8]);
  688.     glNormal3fv(en[6][8]); glTexCoord2fv(tep[6][8]); glVertex3fv(ep[6][8]);
  689.     glEnd();
  690.     glEndList();
  691. }
  692.  
  693. static void Bend_forward(void)
  694. {
  695.     glTranslatef(0.0, 1.0, 0.0);
  696.     glRotatef(90.0, 1, 0, 0);
  697.     glTranslatef(0.0, -1.0, 0.0);
  698. }
  699.  
  700. static void Bend_left(void)
  701. {
  702.     glRotatef(-90.0, 0, 0, 1);
  703.     glTranslatef(0.0, 1.0, 0.0);
  704.     glRotatef(90.0, 1, 0, 0);
  705.     glTranslatef(0.0, -1.0, 0.0);
  706. }
  707.  
  708. static void Bend_right(void)
  709. {
  710.     glRotatef(90.0, 0, 0, 1);
  711.     glTranslatef(0.0, 1.0, 0.0);
  712.     glRotatef(90.0, 1, 0, 0);
  713.     glTranslatef(0.0, -1.0, 0.0);
  714. }
  715.  
  716. static void Build_logo(void)
  717. {
  718.     glNewList(logo, GL_COMPILE);
  719.     glTranslatef(5.5, -3.5, 4.5);
  720.     glTranslatef(0.0, 0.0, -7.0);
  721.     glIndexi(GRAY);
  722.     glColor3f(1, 0, 0); 
  723.     glCallList(doubleCylinder);
  724.     Bend_forward();
  725.     glColor3f(0, 1, 0);
  726.     glCallList(elbow);
  727.     glTranslatef(0.0, 0.0, -7.0);
  728.     glColor3f(1, 0, 0);
  729.     glCallList(doubleCylinder);
  730.     Bend_forward();
  731.     glColor3f(0, 1, 0);
  732.     glCallList(elbow);
  733.     glTranslatef(0.0, 0.0, -5.0);
  734.     glColor3f(1, 1, 0);
  735.     glCallList(singleCylinder);
  736.     Bend_right();
  737.     glColor3f(0, 1, 0);
  738.     glCallList(elbow);
  739.     glTranslatef(0.0, 0.0, -7.0);
  740.     glColor3f(1, 0, 0);
  741.     glCallList(doubleCylinder);
  742.     Bend_forward();
  743.     glColor3f(0, 1, 0);
  744.     glCallList(elbow);
  745.     glTranslatef(0.0, 0.0, -7.0);
  746.     glColor3f(1, 0, 0);
  747.     glCallList(doubleCylinder);
  748.     Bend_forward();
  749.     glColor3f(0, 1, 0);
  750.     glCallList(elbow);
  751.     glTranslatef(0.0, 0.0, -5.0);
  752.     glColor3f(1, 1, 0);
  753.     glCallList(singleCylinder);
  754.     Bend_left();
  755.     glColor3f(0, 1, 0);
  756.     glCallList(elbow);
  757.     glTranslatef(0.0, 0.0, -7.0);
  758.     glColor3f(1, 0, 0);
  759.     glCallList(doubleCylinder);
  760.     Bend_forward();
  761.     glColor3f(0, 1, 0);
  762.     glCallList(elbow);
  763.     glTranslatef(0.0, 0.0, -7.0);
  764.     glColor3f(1, 0, 0);
  765.     glCallList(doubleCylinder);
  766.     Bend_forward();
  767.     glColor3f(0, 1, 0);
  768.     glCallList(elbow);
  769.     glTranslatef(0.0, 0.0, -5.0);
  770.     glColor3f(1, 1, 0);
  771.     glCallList(singleCylinder);
  772.     Bend_right();
  773.     glColor3f(0, 1, 0);
  774.     glCallList(elbow);
  775.     glTranslatef(0.0, 0.0, -7.0);
  776.     glColor3f(1, 0, 0);
  777.     glCallList(doubleCylinder);
  778.     Bend_forward();
  779.     glColor3f(0, 1, 0);
  780.     glCallList(elbow);
  781.     glTranslatef(0.0, 0.0, -7.0);
  782.     glColor3f(1, 0, 0);
  783.     glCallList(doubleCylinder);
  784.     Bend_forward();
  785.     glColor3f(0, 1, 0);
  786.     glCallList(elbow);
  787.     glTranslatef(0.0, 0.0, -5.0);
  788.     glColor3f(1, 1, 0);
  789.     glCallList(singleCylinder);
  790.     Bend_left();
  791.     glColor3f(0, 1, 0);
  792.     glCallList(elbow);
  793.     glTranslatef(0.0, 0.0, -7.0);
  794.     glColor3f(1, 0, 0);
  795.     glCallList(doubleCylinder);
  796.     Bend_forward();
  797.     glColor3f(0, 1, 0);
  798.     glCallList(elbow);
  799.     glTranslatef(0.0, 0.0, -7.0);
  800.     glColor3f(1, 0, 0);
  801.     glCallList(doubleCylinder);
  802.     Bend_forward();
  803.     glColor3f(0, 1, 0);
  804.     glCallList(elbow);
  805.     glTranslatef(0.0, 0.0, -5.0);
  806.     glColor3f(1, 1, 0);
  807.     glCallList(singleCylinder);
  808.     Bend_right();
  809.     glColor3f(0, 1, 0);
  810.     glCallList(elbow);
  811.     glTranslatef(0.0, 0.0, -7.0);
  812.     glColor3f(1, 0, 0);
  813.     glCallList(doubleCylinder);
  814.     Bend_forward();
  815.     glColor3f(0, 1, 0);
  816.     glCallList(elbow);
  817.     glTranslatef(0.0, 0.0, -7.0);
  818.     glColor3f(1, 0, 0);
  819.     glCallList(doubleCylinder);
  820.     Bend_forward();
  821.     glColor3f(0, 1, 0);
  822.     glCallList(elbow);
  823.     glTranslatef(0.0, 0.0, -5.0);
  824.     glColor3f(1, 1, 0);
  825.     glCallList(singleCylinder);
  826.     Bend_left();
  827.     glColor3f(0, 1, 0);
  828.     glCallList(elbow);
  829.     glEndList();
  830. }
  831.  
  832. static void Build_lists(void)
  833. {
  834.     singleCylinder = glGenLists(1);
  835.     doubleCylinder = glGenLists(1);
  836.     elbow = glGenLists(1);
  837.     logo = glGenLists(1);
  838.  
  839.     Build_single_cylinder();
  840.     Build_double_cylinder();
  841.     Build_elbow();
  842.     Build_logo();
  843. }
  844.  
  845.  
  846. static void Init(void)
  847. {
  848.     static float ambient[] = {0.1, 0.1, 0.1, 1.0};
  849.     static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
  850.     static float position[] = {90.0, 90.0, 150.0, 0.0};
  851.     static float front_mat_shininess[] = {30.0};
  852.     static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
  853.     static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
  854.     static float back_mat_shininess[] = {50.0};
  855.     static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
  856.     static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
  857.     static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
  858.     static float lmodel_twoside[] = {GL_TRUE};
  859.     
  860.     glFrontFace(GL_CW);
  861.     glEnable(GL_DEPTH_TEST);
  862.     glDepthFunc(GL_LEQUAL);
  863.  
  864.     glMatrixMode(GL_PROJECTION);
  865.     glLoadIdentity();
  866.     gluPerspective(90, 1.0, 1.0, 200.0);
  867.     glMatrixMode(GL_MODELVIEW);
  868.     glClearColor(0.0, 0.0, 0.0, 0.0);
  869.     glClearStencil(0);
  870.     glClearAccum(0,0,0,0);
  871.     glViewport(0, 0, W, H);
  872.  
  873.     glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  874.     glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  875.     glLightfv(GL_LIGHT0, GL_POSITION, position);
  876.     
  877.     glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
  878.     glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
  879.     glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  880.     glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
  881.     glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
  882.     glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  883.  
  884.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  885.     glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  886.  
  887.     glEnable(GL_LIGHTING);
  888.     glEnable(GL_LIGHT0);
  889.     glEnable(GL_CLIP_PLANE0);
  890.  
  891.     if (rgb) {
  892.     static float fog_color[] = {0.0, 0.0, 0.0, 1.0};
  893.  
  894.     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  895.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  896.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  897.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nearest);
  898.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nearest);
  899.     glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, checkImageHeight, 0,
  900.              GL_RGB, GL_UNSIGNED_BYTE, checkImage);
  901.     glEnable(GL_TEXTURE_2D);
  902.     texturing = 1;
  903.     glEnable(GL_CULL_FACE);
  904.     culling = 1;
  905.     glCullFace(GL_BACK);
  906.     cullface = GL_BACK;
  907.  
  908.     glFogf(GL_FOG_END, 20.0);
  909.     glFogf(GL_FOG_START, 2.0);
  910.     glFogi(GL_FOG_MODE, GL_LINEAR);
  911.     glFogfv(GL_FOG_COLOR, fog_color);
  912.     }
  913.  
  914.     Build_lists();
  915. }
  916.  
  917. GLfloat newMatrix[16] = {
  918.     1, 0, 0, 0,
  919.     0, 1, 0, 0,
  920.     0, 0, 1, 0,
  921.     0, 0, 0, 1,
  922. };
  923.  
  924. static void xformViewport(int vpx, int vpy, int vpw, int vph)
  925. {
  926.     GLfloat origMatrix[16];
  927.     GLfloat halfwidth, halfheight, xcenter, ycenter;
  928.     int i;
  929.  
  930.     glEnable(GL_SCISSOR_TEST); 
  931.     glScissor(vpx, vpy, vpw, vph);
  932.  
  933.     /*
  934.     ** In the general case, we have to push the viewport out half of the
  935.     ** width of a line and the farthest distance which a DrawPixels or 
  936.     ** consecutive glBitmap calls might move.
  937.     **
  938.     ** For now, we push the viewport out a distance of one because there are
  939.     ** no Bitmap rendering calls in the inner loop, and lines are always a 
  940.     ** width of one.
  941.     */
  942.     for (i=0; i<1; i++) {
  943.     if (vpx > 0) {
  944.         vpx--;
  945.         vpw++;
  946.     }
  947.     if (vpy > 0) {
  948.         vpy--;
  949.         vph++;
  950.     }
  951.     if (vpx + vpw < W) {
  952.         vpw++;
  953.     }
  954.     if (vpy + vph < H) {
  955.         vph++;
  956.     }
  957.     }
  958.  
  959.     glViewport(vpx, vpy, vpw, vph);
  960.  
  961.     glGetFloatv(GL_PROJECTION_MATRIX, origMatrix);
  962.  
  963.     glMatrixMode(GL_PROJECTION);
  964.     glPushMatrix();
  965.  
  966.     glLoadIdentity();
  967.  
  968.     halfwidth = vpw / 2.0;
  969.     halfheight = vph / 2.0;
  970.     xcenter = vpx + halfwidth;
  971.     ycenter = vpy + halfheight;
  972.     newMatrix[0] = 1 / halfwidth;
  973.     newMatrix[5] = 1 / halfheight;
  974.     newMatrix[12] = -xcenter / halfwidth;
  975.     newMatrix[13] = -ycenter / halfheight;
  976.     glMultMatrixf(newMatrix);
  977.  
  978.     newMatrix[0] = W / 2.0;
  979.     newMatrix[5] = H / 2.0;
  980.     newMatrix[12] = W / 2.0;
  981.     newMatrix[13] = H / 2.0;
  982.     glMultMatrixf(newMatrix);
  983.  
  984.     glMultMatrixf(origMatrix);
  985. }
  986.  
  987. static void unxformViewport(int vpx, int vpy, int vpw, int vph)
  988. {
  989.     glDisable(GL_SCISSOR_TEST);
  990.     glViewport(0, 0, W, H);
  991.     glMatrixMode(GL_PROJECTION);
  992.     glPopMatrix();
  993. }
  994.  
  995. static void DrawIt(void)
  996. {
  997.     glMatrixMode(GL_MODELVIEW);
  998.     glPushMatrix();
  999.     glTranslatef(0, 0, zTranslation);
  1000.     glRotatef(30.0, 1, 0, 0);
  1001.     glRotatef(yRotation, 0, 1, 0);
  1002.     glClipPlane(GL_CLIP_PLANE0, plane);
  1003.  
  1004.     if (decimation == 1) { 
  1005.     glCallList(logo);
  1006.     } else {
  1007.     int i, j;
  1008.     int vpx, vpy, vpw, vph;
  1009.  
  1010.     for (i=decimation-1; i>=0; i--) {
  1011.         for (j=0; j<decimation; j++) {
  1012.         vpx = i*W/decimation;
  1013.         vpw = (i+1)*W/decimation - vpx;
  1014.         vpy = j*H/decimation;
  1015.         vph = (j+1)*H/decimation - vpy;
  1016.  
  1017.         if (vpw > 0 && vph > 0) {
  1018.             xformViewport(vpx, vpy, vpw, vph);
  1019.  
  1020.             glMatrixMode(GL_MODELVIEW);
  1021.             glPushMatrix();
  1022.  
  1023.             glCallList(logo);
  1024.  
  1025.             glMatrixMode(GL_MODELVIEW);
  1026.             glPopMatrix();
  1027.  
  1028.             unxformViewport(vpx, vpy, vpw, vph);
  1029.         }
  1030.         }
  1031.     }
  1032.     }
  1033.  
  1034.     glMatrixMode(GL_MODELVIEW);
  1035.     glPopMatrix();
  1036. }
  1037.  
  1038. #define NUM_SAMPLES 6
  1039. static float jitter[NUM_SAMPLES][2] = {
  1040.     0.693609,0.450580, 0.306164,0.949401, 0.041299,0.249607,
  1041.     0.959197,0.750780, 0.693563,0.050253, 0.306169,0.549378,
  1042. };
  1043.  
  1044. void jitterWindow(float x, float y)
  1045. {
  1046.     GLfloat matrix[16];
  1047.  
  1048.     /* Jitter projection matrix */
  1049.     glMatrixMode(GL_PROJECTION);
  1050.     glGetFloatv(GL_PROJECTION_MATRIX, matrix);
  1051.     glLoadIdentity();
  1052.     glTranslatef(2*x/W, 2*y/H, 0);
  1053.     glMultMatrixf(matrix);
  1054. }
  1055.  
  1056. static void feedbackVert(GLint *count, GLint total)
  1057. {
  1058.     int i;
  1059.     int valuesLeft;
  1060.     int valuesNeeded;
  1061.  
  1062.     i = *count;
  1063.     valuesLeft = total-i-1;
  1064.     if (texturing) {
  1065.     valuesNeeded=11;
  1066.     } else {
  1067.     valuesNeeded=7;
  1068.     }
  1069.     /*
  1070.     ** Data stored in feedbackBuf:
  1071.     ** i+1 - location (x,y,z)
  1072.     ** i+4 - color (r,g,b,a)
  1073.     ** i+7 - texture coords (s,t,r,q)
  1074.     */
  1075.     if (valuesLeft >= valuesNeeded) {
  1076.     glColor4fv(feedbackBuf+i+4);
  1077.     if (texturing) {
  1078.         glTexCoord4fv(feedbackBuf+i+8);
  1079.     }
  1080.     glVertex3fv(feedbackBuf+i+1);
  1081.     i += valuesNeeded;
  1082.     } else {
  1083.     i = total;
  1084.     }
  1085.     *count = i;
  1086. }
  1087.  
  1088. static void DoDisplay(void)
  1089. {
  1090.     GLint i, max;
  1091.  
  1092.     if (jittering) max = NUM_SAMPLES;
  1093.     else max = 1;
  1094.  
  1095.     if (jittering) {
  1096.     glClear(GL_ACCUM_BUFFER_BIT);
  1097.     }
  1098.     for (i=0; i<max; i++) {
  1099.     if (jittering) {
  1100.         glMatrixMode(GL_PROJECTION);
  1101.         glPushMatrix();
  1102.         jitterWindow(jitter[i][0]-0.5, jitter[i][1]-0.5);
  1103.     }
  1104.     glClear(clearMask);
  1105.     if (capping) {
  1106.         glStencilFunc(GL_ALWAYS, 1, 1);
  1107.         glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
  1108.     }
  1109.     if (feedbackmode) {
  1110.         if (texturing) {
  1111.         glFeedbackBuffer(MAX_FEED, GL_3D_COLOR_TEXTURE, feedbackBuf);
  1112.         } else {
  1113.         glFeedbackBuffer(MAX_FEED, GL_3D_COLOR, feedbackBuf);
  1114.         }
  1115.         (void) glRenderMode(GL_FEEDBACK);
  1116.     }
  1117.     DrawIt();
  1118.     if (capping) {
  1119.         if (clipPlane) glDisable(GL_CLIP_PLANE0);
  1120.         if (lighting) glDisable(GL_LIGHTING);
  1121.         if (culling) glDisable(GL_CULL_FACE);
  1122.         if (texturing) glDisable(GL_TEXTURE_2D);
  1123.  
  1124.         if (rgb) {
  1125.         glColor3f(1.0,1.0,1.0);
  1126.         } else {
  1127.         glIndexf(7);
  1128.         }
  1129.         glStencilFunc(GL_EQUAL, 1, 1);
  1130.  
  1131.         glMatrixMode(GL_MODELVIEW);
  1132.         glPushMatrix();
  1133.         glTranslatef(0, 0, zTranslation);
  1134.         glRotatef(30.0, 1, 0, 0);
  1135.         glRotatef(yRotation, 0, 1, 0);
  1136.         glBegin(GL_QUADS);
  1137.         glVertex3f( 10,  10,  10+plane[3]);
  1138.         glVertex3f(-10,  10, -10+plane[3]);
  1139.         glVertex3f(-10, -10, -10+plane[3]);
  1140.         glVertex3f( 10, -10,  10+plane[3]);
  1141.         glEnd();
  1142.         glPopMatrix();
  1143.  
  1144.         if (texturing) glEnable(GL_TEXTURE_2D);
  1145.         if (culling) glEnable(GL_CULL_FACE);
  1146.         if (lighting) glEnable(GL_LIGHTING);
  1147.         if (clipPlane) glEnable(GL_CLIP_PLANE0);
  1148.     }
  1149.     if (jittering) {
  1150.         glMatrixMode(GL_PROJECTION);
  1151.         glPopMatrix();
  1152.         glAccum(GL_ACCUM, 1.0/max);
  1153.     }
  1154.     }
  1155.     if (feedbackmode) {
  1156.     GLint things;
  1157.     GLint token;
  1158.     GLint n;
  1159.  
  1160.     things = glRenderMode(GL_RENDER);
  1161.     if (things < 0) things = MAX_FEED;
  1162.  
  1163.     glMatrixMode(GL_PROJECTION);
  1164.     glPushMatrix();
  1165.     glLoadIdentity();
  1166.     glOrtho(0, W, 0, H, 1, -1);
  1167.  
  1168.     if (clipPlane) glDisable(GL_CLIP_PLANE0);
  1169.     if (lighting) glDisable(GL_LIGHTING);
  1170.     if (culling) glDisable(GL_CULL_FACE);
  1171.     if (capping) glDisable(GL_STENCIL_TEST);
  1172.  
  1173.     for (i=0; i<things; i++) {
  1174.         token = feedbackBuf[i];
  1175.         switch(token) {
  1176.           case GL_POLYGON_TOKEN:
  1177.         glBegin(GL_POLYGON);
  1178.         i++;
  1179.         if (i != things) {
  1180.             n = feedbackBuf[i];
  1181.             while (n--) {
  1182.             feedbackVert(&i, things);
  1183.             }
  1184.         }
  1185.         glEnd();
  1186.         break;
  1187.           case GL_LINE_TOKEN:
  1188.           case GL_LINE_RESET_TOKEN:
  1189.         glBegin(GL_LINES);
  1190.         feedbackVert(&i, things);
  1191.         feedbackVert(&i, things);
  1192.         glEnd();
  1193.         break;
  1194.           case GL_POINT_TOKEN:
  1195.         glBegin(GL_POINTS);
  1196.         feedbackVert(&i, things);
  1197.         glEnd();
  1198.         break;
  1199.           default:
  1200.             printf("%9.2f?\n", feedbackBuf[i]);
  1201.             break;
  1202.         }
  1203.     }
  1204.  
  1205.     if (capping) glEnable(GL_STENCIL_TEST);
  1206.     if (culling) glEnable(GL_CULL_FACE);
  1207.     if (lighting) glEnable(GL_LIGHTING);
  1208.     if (clipPlane) glEnable(GL_CLIP_PLANE0);
  1209.  
  1210.     glMatrixMode(GL_MODELVIEW);
  1211.     glPushMatrix();
  1212.     glLoadIdentity();
  1213.  
  1214.     glPopMatrix();
  1215.  
  1216.     glMatrixMode(GL_PROJECTION);
  1217.     glPopMatrix();
  1218.     }
  1219.     if (motionblur) {
  1220.     glAccum(GL_MULT, 0.7);
  1221.     glAccum(GL_ACCUM, 0.3);
  1222.     }
  1223.     if (jittering || motionblur) {
  1224.     glAccum(GL_RETURN, 1.0);
  1225.     }
  1226.     glFinish();
  1227. }
  1228.  
  1229. static void SetAntiAliasedGrayScale(void)
  1230. {
  1231.     XColor *xc;
  1232.     float color;
  1233.     long i, j, cells;
  1234.  
  1235.     if (indexBits < 8) return;
  1236.  
  1237.     cells = 1 << indexBits;
  1238.     xc = (XColor *) malloc(cells * sizeof(XColor));
  1239.  
  1240.     for (i = 0; i < 16; i++) {
  1241.     color = (2 * i + 1) / 32.0;
  1242.     for (j = 0; j < 16; j++) {
  1243.         xc[i].pixel = i * 16 + j;
  1244.         xc[i].red = (color * j / 15.0) * 65535.0;
  1245.         xc[i].green = xc[i].red;
  1246.         xc[i].blue = xc[i].red;
  1247.         xc[i].flags = DoRed | DoGreen | DoBlue;
  1248.     }
  1249.     }
  1250.     XStoreColors(dpy, cmap, xc, cells);
  1251.  
  1252.     free((void *) xc);
  1253. }
  1254.  
  1255. static void SetGrayRamp(void)
  1256. {
  1257.     XColor *xc;
  1258.     float color;
  1259.     long i, cells;
  1260.  
  1261.     cells = 1 << indexBits;
  1262.     xc = (XColor *) malloc(cells * sizeof(XColor));
  1263.  
  1264.     for (i = 0; i < cells; i++) {
  1265.     xc[i].pixel = i;
  1266.     xc[i].red = ((float)i / (float)(cells - 1)) * 65535.0;
  1267.     xc[i].green = xc[i].red;
  1268.     xc[i].blue = xc[i].red;
  1269.     xc[i].flags = DoRed | DoGreen | DoBlue;
  1270.     }
  1271.     XStoreColors(dpy, cmap, xc, cells);
  1272.  
  1273.     free((void *) xc);
  1274. }
  1275.  
  1276. static void Usage(void)
  1277. {
  1278.     printf("Usage: tlogo [-c] [-s] [-f xfont] [-geometry WxH+X+Y\n");
  1279.     printf("   -c:  Run in color index mode\n");
  1280.     printf("   -s:  Run in single buffered mode\n");
  1281.     printf("   -f:  Choose a new X font to use\n");
  1282.     printf("   -geometry:  specify window size and location\n");
  1283.     exit(-1);
  1284. }
  1285.  
  1286. static void LoadFont(const char *fontName)
  1287. {
  1288.     XFontStruct *fontInfo;
  1289.     unsigned long first, last;
  1290.  
  1291.     /* Lookup font */
  1292.     fontInfo = XLoadQueryFont(dpy, fontName);
  1293.     if (fontInfo == NULL) {
  1294.     fprintf(stderr, "Can't find font \"%s\"\n", fontName);
  1295.     return;
  1296.     }
  1297.  
  1298.     first = fontInfo->min_char_or_byte2;
  1299.     last = fontInfo->max_char_or_byte2;
  1300.  
  1301.     fontBase = glGenLists(last+1);
  1302.     if (fontBase == 0) {
  1303.     fprintf(stderr, "Out of list space\n");
  1304.     return;
  1305.     }
  1306.     glXUseXFont(fontInfo->fid, first, last-first+1, fontBase+first);
  1307.     fontWidth = fontInfo->max_bounds.width;
  1308.     fontHeight = fontInfo->ascent + fontInfo->descent;
  1309. }
  1310.  
  1311. static void ShowFrames(double start, double stop)
  1312. {
  1313.     char buf[20];
  1314.     sprintf(buf, "%4.1f frames/sec", 1.0 / (stop - start));
  1315.  
  1316.     glPushAttrib(GL_ENABLE_BIT | GL_TRANSFORM_BIT);
  1317.     glMatrixMode(GL_MODELVIEW);
  1318.     glPushMatrix();
  1319.     glLoadIdentity();
  1320.     glMatrixMode(GL_PROJECTION);
  1321.     glPushMatrix();
  1322.     glLoadIdentity();
  1323.     glOrtho(-0.5, W - 0.5, -0.5, H - 0.5, -1, 1);
  1324.  
  1325.     glDisable(GL_LIGHTING);
  1326.     glDisable(GL_TEXTURE_2D);
  1327.     glDisable(GL_FOG);
  1328.     glDisable(GL_DEPTH_TEST);
  1329.     glDisable(GL_CLIP_PLANE0);
  1330.  
  1331.     glColor3f(1, 1, 1); glIndexi(WHITE);
  1332.     glRasterPos2f(10, fontHeight + 10);
  1333.     glListBase(fontBase);
  1334.     glCallLists(strlen(buf), GL_UNSIGNED_BYTE, buf);
  1335.  
  1336.     glPopMatrix();
  1337.     glMatrixMode(GL_MODELVIEW);
  1338.     glPopMatrix();
  1339.  
  1340.     glPopAttrib();
  1341. }
  1342.  
  1343. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  1344. {
  1345.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  1346.     return GL_TRUE;
  1347.     }
  1348.     return GL_FALSE;
  1349. }
  1350.  
  1351. double Now(void)
  1352. {
  1353. #ifdef __unix
  1354.     struct tms tm;
  1355.     long clk;
  1356.  
  1357.     clk = times(&tm);
  1358.     return (double)clk / (double)HZ;
  1359. #else
  1360.     return 0;
  1361. #endif
  1362. }
  1363.  
  1364. int main(int argc, char** argv)
  1365. {
  1366.     int *attrs, i, rv;
  1367.     XVisualInfo *vi;
  1368.     XSetWindowAttributes swa;
  1369.     XSizeHints sizehints;
  1370.     XEvent ev;
  1371.     GLXContext cx;
  1372.     GLboolean needDisplay = 1;
  1373.     KeySym ks;
  1374.     char buf[10];
  1375.     GLboolean animate = GL_FALSE;
  1376.     GLboolean showFrames = GL_FALSE;
  1377.     char *geometry = NULL;
  1378.     double start;
  1379.  
  1380.     rgb = 1;
  1381.     doubleBuffer = 1;
  1382.  
  1383.     for (i = 1; i < argc; i++) {
  1384.     if (!strcmp(argv[i], "-geometry")) {
  1385.         i++;
  1386.         geometry = argv[i];
  1387.         if (geometry == NULL) {
  1388.         Usage();
  1389.         }
  1390.     } else if (argv[i][0] == '-') {
  1391.         switch (argv[i][1]) {
  1392.           case 'c':
  1393.         rgb = 0;
  1394.         break;
  1395.           case 's':
  1396.         doubleBuffer = 0;
  1397.         break;
  1398.           case 'f':
  1399.         if (i == argc - 1) {
  1400.             Usage();
  1401.         }
  1402.         fontName = argv[++i];
  1403.         break;
  1404.           default:
  1405.         Usage();
  1406.         }
  1407.     } else {
  1408.         Usage();
  1409.     }
  1410.     }
  1411.  
  1412.     if (doubleBuffer) {
  1413.     if (rgb) {
  1414.         attrs = RGBA_DB_attributes;
  1415.     } else {
  1416.         attrs = CI_DB_attributes;
  1417.     }
  1418.     } else {
  1419.     if (rgb) {
  1420.         attrs = RGBA_SB_attributes;
  1421.     } else {
  1422.         attrs = CI_SB_attributes;
  1423.     }
  1424.     }
  1425.  
  1426.     dpy = XOpenDisplay(0);
  1427.     if (!dpy) {
  1428.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  1429.     return -1;
  1430.     }
  1431.  
  1432.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attrs);
  1433.     if (!vi) {
  1434.     fprintf(stderr, "No matching visual on \"%s\"\n",
  1435.         getenv("DISPLAY"));
  1436.     return -1;
  1437.     }
  1438.  
  1439.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  1440.                rgb ? AllocNone : AllocAll);
  1441.     sizehints.flags = PPosition | PSize;
  1442.     sizehints.width = W;
  1443.     sizehints.height = H;
  1444.     sizehints.x = 10;
  1445.     sizehints.y = 10;
  1446.     if(geometry) {
  1447.     int flags, x, y, width, height;
  1448.  
  1449.     flags = XParseGeometry(geometry, &x, &y,
  1450.                    (unsigned int *)&width,
  1451.                    (unsigned int *)&height);
  1452.         if(WidthValue & flags) {
  1453.         sizehints.flags |= USSize;
  1454.         sizehints.width = width;
  1455.         W = width;
  1456.     }
  1457.     if(HeightValue & flags) {
  1458.         sizehints.flags |= USSize;
  1459.         sizehints.height = height;
  1460.         H = height;
  1461.     }
  1462.     if(XValue & flags) {
  1463.         if(XNegative & flags)
  1464.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  1465.             - sizehints.width;
  1466.             sizehints.flags |= USPosition;
  1467.         sizehints.x = x;
  1468.     }
  1469.     if(YValue & flags) {
  1470.         if(YNegative & flags)
  1471.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  1472.             - sizehints.height;
  1473.             sizehints.flags |= USPosition;
  1474.         sizehints.y = y;
  1475.     }
  1476.     }
  1477.     swa.border_pixel = 0;
  1478.     swa.colormap = cmap;
  1479.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask;
  1480.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
  1481.                            sizehints.x, sizehints.y,
  1482.                sizehints.width, sizehints.height,
  1483.                0, vi->depth, InputOutput, vi->visual,
  1484.                CWBorderPixel|CWColormap|CWEventMask, &swa);
  1485.     XSetStandardProperties(dpy, window, "tlogo test", "tlogo", None,
  1486.                            argv, argc, &sizehints);
  1487.     XSetWMColormapWindows(dpy, window, &window, 1);
  1488.     XMapWindow(dpy, window);
  1489.     XIfEvent(dpy, &ev, WaitForMapNotify, (char*)window);
  1490.  
  1491.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  1492.     if (!glXMakeCurrent(dpy, window, cx)) {
  1493.     fprintf(stderr, "Can't make window current to context\n");
  1494.     return -1;
  1495.     }
  1496.  
  1497.     if (!rgb) {
  1498.     glGetIntegerv(GL_INDEX_BITS, &indexBits);
  1499.     SetGrayRamp();
  1500.     colorIndexes[0] = BLACK;
  1501.     colorIndexes[1] = GRAY;
  1502.     colorIndexes[2] = WHITE;
  1503.     glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes);
  1504.     }
  1505.  
  1506.     Init();
  1507.     LoadFont(fontName);
  1508.  
  1509.     for (;;) {
  1510.     while (XPending(dpy) != 0) {
  1511.         XNextEvent(dpy, &ev);
  1512.         switch (ev.type) {
  1513.           case Expose:
  1514.         needDisplay = GL_TRUE;
  1515.         break;
  1516.           case ConfigureNotify:
  1517.         W = ev.xconfigure.width;
  1518.         H = ev.xconfigure.height;
  1519.         glViewport(0, 0, W, H);
  1520.         needDisplay = GL_TRUE;
  1521.         break;
  1522.           case KeyPress:
  1523.         rv = XLookupString(&ev.xkey, buf, sizeof(buf), &ks, 0);
  1524.         needDisplay = GL_TRUE;
  1525.         switch (ks) {
  1526.           case XK_Escape:
  1527.             glXDestroyContext(dpy, cx);
  1528.             XCloseDisplay(dpy);
  1529.             return 0;
  1530.           case XK_space:
  1531.             animate = !animate;
  1532.             break;
  1533.           case XK_question:
  1534.             showFrames = !showFrames;
  1535.             break;
  1536.  
  1537.           case XK_Left:
  1538.             yRotation += 0.5;
  1539.             break;
  1540.           case XK_Right:
  1541.             yRotation -= 0.5;
  1542.             break;
  1543.           case XK_Up:
  1544.             plane[3] += 2.0;
  1545.             break;
  1546.           case XK_Down:
  1547.             plane[3] -= 2.0;
  1548.             break;
  1549.           case XK_Z:
  1550.             zTranslation -= 1.0;
  1551.             break;
  1552.           case XK_z:
  1553.             zTranslation += 1.0;
  1554.             break;
  1555.  
  1556.           case XK_1:
  1557.             glPolygonMode(polymode, GL_FILL);
  1558.             break;
  1559.           case XK_2:
  1560.             glPolygonMode(polymode, GL_POINT);
  1561.             break;
  1562.           case XK_3:
  1563.             glPolygonMode(polymode, GL_LINE);
  1564.             break;
  1565.           case XK_p: case XK_P:
  1566.             needDisplay = GL_FALSE;
  1567.             switch (polymode) {
  1568.               case GL_BACK:
  1569.             polymode = GL_FRONT;
  1570.             printf("Polymode now GL_FRONT\n");
  1571.             break;
  1572.               case GL_FRONT:
  1573.             polymode = GL_FRONT_AND_BACK;
  1574.             printf("Polymode now GL_FRONT_AND_BACK\n");
  1575.             break;
  1576.               case GL_FRONT_AND_BACK:
  1577.             polymode = GL_BACK;
  1578.             printf("Polymode now GL_BACK\n");
  1579.             break;
  1580.             }
  1581.             break;
  1582.  
  1583.           case XK_4:
  1584.             glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  1585.             break;
  1586.           case XK_5:
  1587.             glEnable(GL_POLYGON_SMOOTH);
  1588.             if (rgb) {
  1589.             glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  1590.             glEnable(GL_BLEND);
  1591.             glDisable(GL_DEPTH_TEST);
  1592.             } else {
  1593.             SetAntiAliasedGrayScale();
  1594.             }
  1595.             break;
  1596.           case XK_6:
  1597.             glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  1598.             glDisable(GL_POLYGON_SMOOTH);
  1599.             if (rgb) {
  1600.             glBlendFunc(GL_ONE, GL_ZERO);
  1601.             glDisable(GL_BLEND);
  1602.             glEnable(GL_DEPTH_TEST);
  1603.             } else {
  1604.             SetGrayRamp();
  1605.             }
  1606.             break;
  1607.  
  1608.           case XK_7:
  1609.             glPolygonStipple(stipple);
  1610.             glEnable(GL_POLYGON_STIPPLE);
  1611.             break;
  1612.           case XK_8:
  1613.             glDisable(GL_POLYGON_STIPPLE);
  1614.             break;
  1615.  
  1616.           case XK_9:
  1617.             glShadeModel(GL_FLAT);
  1618.             break;
  1619.           case XK_0:
  1620.             glShadeModel(GL_SMOOTH);
  1621.             break;
  1622.  
  1623.           case XK_Q: 
  1624.             glEnable(GL_CULL_FACE);
  1625.             culling = 1;
  1626.             glCullFace(GL_FRONT_AND_BACK);
  1627.             cullface = GL_FRONT_AND_BACK;
  1628.             break;
  1629.           case XK_q:
  1630.             glDisable(GL_CULL_FACE);
  1631.             culling = 0;
  1632.             break;
  1633.           case XK_W: case XK_w:
  1634.             glEnable(GL_CULL_FACE);
  1635.             culling = 1;
  1636.             glCullFace(GL_FRONT);
  1637.             cullface = GL_FRONT;
  1638.             break;
  1639.           case XK_E: case XK_e:
  1640.             glEnable(GL_CULL_FACE);
  1641.             culling = 1;
  1642.             glCullFace(GL_BACK);
  1643.             cullface = GL_BACK;
  1644.             break;
  1645.  
  1646.           case XK_R: case XK_r:
  1647.             glFrontFace(GL_CW);
  1648.             break;
  1649.           case XK_T: case XK_t: 
  1650.             glFrontFace(GL_CCW);
  1651.             break;
  1652.           case XK_Y: case XK_y:
  1653.             glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  1654.             glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
  1655.             glPolygonStipple(stipple);
  1656.             break;
  1657.           case XK_U: case XK_u:
  1658.             glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  1659.             glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
  1660.             glPolygonStipple(stipple);
  1661.             break;
  1662.  
  1663.           case XK_A: case XK_a:
  1664.             glEnable(GL_TEXTURE_2D);
  1665.             texturing = 1;
  1666.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  1667.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  1668.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  1669.                      nearest);
  1670.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1671.                      nearest);
  1672.             glTexImage2D(GL_TEXTURE_2D, 0, 4, brickImageWidth,
  1673.                  brickImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  1674.                  (const unsigned char*) brickImage);
  1675.             break;
  1676.           case XK_S: case XK_s:
  1677.             glEnable(GL_TEXTURE_2D);
  1678.             texturing = 1;
  1679.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat);
  1680.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat);
  1681.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  1682.                      nearest);
  1683.             glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1684.                      nearest);
  1685.             glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
  1686.                  checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
  1687.                  (const unsigned char*) checkImage);
  1688.             break;
  1689.           case XK_D: case XK_d:
  1690.             glDisable(GL_TEXTURE_2D);
  1691.             texturing = 0;
  1692.             break;
  1693.  
  1694.           case XK_F: case XK_f:
  1695.             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, decal);
  1696.             break;
  1697.           case XK_G: case XK_g:
  1698.             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, modulate);
  1699.             break;
  1700.  
  1701.           case XK_H: case XK_h:
  1702.             dodither = !dodither;
  1703.             dodither ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
  1704.             break;
  1705.  
  1706.           case XK_L: case XK_l:
  1707.             lighting = !lighting;
  1708.             lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
  1709.             break;
  1710.  
  1711.           case XK_K: case XK_k:
  1712.             twoside = !twoside;
  1713.             glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, twoside);
  1714.             break;
  1715.  
  1716.           case XK_I: case XK_i:
  1717.             fog = !fog;
  1718.             fog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  1719.             break;
  1720.           case XK_J: case XK_j:
  1721.             depth = !depth;
  1722.             if (depth) {
  1723.             glEnable(GL_DEPTH_TEST);
  1724.             clearMask |= GL_DEPTH_BUFFER_BIT;
  1725.             } else {
  1726.             glDisable(GL_DEPTH_TEST);
  1727.             clearMask &= ~GL_DEPTH_BUFFER_BIT;
  1728.             }
  1729.             break;
  1730.  
  1731.           case XK_X: case XK_x:
  1732.             clipPlane = !clipPlane;
  1733.             if (clipPlane)
  1734.             glEnable(GL_CLIP_PLANE0);
  1735.             else
  1736.             glDisable(GL_CLIP_PLANE0);
  1737.             break;
  1738.           case XK_C: case XK_c:
  1739.             capping = !capping;
  1740.             if (capping) {
  1741.             clearMask |= GL_STENCIL_BUFFER_BIT;
  1742.             glEnable(GL_STENCIL_TEST);
  1743.             } else {
  1744.             clearMask &= ~GL_STENCIL_BUFFER_BIT;
  1745.             glDisable(GL_STENCIL_TEST);
  1746.             }
  1747.             break;
  1748.           case XK_V: case XK_v:
  1749.             jittering = 1-jittering;
  1750.             if (motionblur) motionblur = 0;
  1751.             if (feedbackmode) feedbackmode = 0;
  1752.             break;
  1753.           case XK_B: case XK_b:
  1754.             motionblur = 1-motionblur;
  1755.             if (motionblur) {
  1756.             glClear(GL_ACCUM_BUFFER_BIT);
  1757.             }
  1758.             if (jittering) jittering = 0;
  1759.             break;
  1760.           case XK_N: case XK_n:
  1761.             feedbackmode = 1-feedbackmode;
  1762.             if (jittering) jittering = 0;
  1763.             break;
  1764.           case XK_M: 
  1765.             decimation--;
  1766.             if (decimation < 1) decimation = 1;
  1767.             break;
  1768.           case XK_m:
  1769.             decimation++;
  1770.             break;
  1771.           default:
  1772.             needDisplay = GL_FALSE;
  1773.             break;
  1774.         }
  1775.         break;
  1776.         }
  1777.     }
  1778.  
  1779.     if (needDisplay || animate) {
  1780.         if (animate) {
  1781.         yRotation += 0.5;
  1782.         }
  1783.         if (showFrames) {
  1784.         start = Now();
  1785.         }
  1786.         DoDisplay();
  1787.         if (doubleBuffer) {
  1788.         glXSwapBuffers(dpy, window);
  1789.         }
  1790.         if (showFrames) {
  1791.         if (doubleBuffer) glDrawBuffer(GL_FRONT);
  1792.         ShowFrames(start, Now());
  1793.         if (doubleBuffer) glDrawBuffer(GL_BACK);
  1794.         }
  1795.         needDisplay = GL_FALSE;
  1796.     }
  1797.     if (!animate) {
  1798.         XPeekEvent(dpy, &ev);
  1799.     }
  1800.     }
  1801. }
  1802.